package loadiconhandler

import (
	"crypto/md5"
	"fmt"
	"gmap-backend/internal/config"
	"gmap-backend/internal/server/manager"
	"gmap-backend/internal/server/vo"
	"gmap-backend/internal/util/httpurlutil"
	"os"
	"path/filepath"
	"strings"
)

type HttpLoadIcon struct {
}

func (owner *HttpLoadIcon) CanHandle(appConfig *config.AppConfig, req *vo.PathReq) (bool, any) {
	urlMatch := strings.HasPrefix(req.Path, "http://") || strings.HasPrefix(req.Path, "https://")
	return urlMatch, nil
}

func (owner *HttpLoadIcon) Handle(appConfig *config.AppConfig, req *vo.PathReq, extra any) *vo.LoadIconResp {
	return GetHttpIconUrl(appConfig, req.Path)
}

// GetHttpIconUrl 提取网站的favicon，如果出错则使用默认浏览器图标返回
func GetHttpIconUrl(appConfig *config.AppConfig, url string) (retVal *vo.LoadIconResp) {
	defer func() {
		if e := recover(); nil != e {
			retVal = &vo.LoadIconResp{
				Url: SPECIAL_PATH_BROWSER,
			}
		}
	}()

	rootUrl := httpurlutil.GetRootUrl(url)
	md5 := fmt.Sprintf("%x", md5.Sum([]byte(rootUrl)))
	cachedResp := FindCachedIcon(appConfig, md5)
	if nil != cachedResp {
		return cachedResp
	}

	succ, tmpPath := manager.LoadFavicon(appConfig, url) // rootUrl
	if !succ {
		panic(fmt.Sprintf("无法获取网站的favicon: %s", url))
	}
	ext := filepath.Ext(tmpPath)
	resultPath := filepath.Join(appConfig.PathConfig.CacheDir, md5+ext)
	resultUrl := "file:///" + strings.TrimSpace(strings.ReplaceAll(resultPath, "\\", "/"))
	if nil != os.Rename(tmpPath, resultPath) {
		panic(fmt.Sprintf("无法保存临时图标到目标位置: %s", tmpPath))
	}
	return &vo.LoadIconResp{Url: resultUrl}
}
